package com.ruoyi.web.controller.system;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.ClassesConstants;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.system.domain.SysClasses;
import com.ruoyi.system.domain.SysDataProperty;
import com.ruoyi.system.domain.vo.R;
import com.ruoyi.system.protocol.IDynamicCacheService;
import com.ruoyi.system.protocol.IDynamicDataCommonService;
import com.ruoyi.system.protocol.IDynamicDataService;
import com.ruoyi.system.protocol.IDynamicTableService;
import com.ruoyi.system.service.ISysClassesService;
import com.ruoyi.system.service.ISysDataPropertyService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysObjectProperty;
import com.ruoyi.system.service.ISysObjectPropertyService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 关联属性Controller
 * 
 * @author ruoyi
 * @date 2022-08-10
 */
@RestController
@RequestMapping("/system/objectProperty")
public class SysObjectPropertyController extends BaseController
{

    @Autowired
    private ISysClassesService sysClassesService;

    @Autowired
    private IDynamicTableService dynamicTableService;

    @Autowired
    private ISysObjectPropertyService sysObjectPropertyService;

    @Autowired
    private IDynamicDataCommonService dynamicDataCommonService;

    @Autowired
    private ISysDataPropertyService sysDataPropertyService;

    @Autowired
    private IDynamicDataService dynamicDataService;

    @Autowired
    private IDynamicCacheService dynamicCacheService;


    /**
     * 查询关联属性列表
     */
//    @PreAuthorize("@ss.hasPermi('system:objectProperty:list')")
    @PreAuthorize("@ss.hasAnyPermi('system:objectProperty:list,system:dynamic:associate')")
    @GetMapping("/list")
    public TableDataInfo list(SysObjectProperty sysObjectProperty)
    {
        startPage();
        List<SysObjectProperty> list = sysObjectPropertyService.selectSysObjectPropertyList(sysObjectProperty);
        return getDataTable(list);
    }

    @GetMapping("/listCount")
    public AjaxResult listCount(SysObjectProperty sysObjectProperty)
    {
        int count = sysObjectPropertyService.count(new LambdaQueryWrapper<SysObjectProperty>().eq(SysObjectProperty::getClassesId, sysObjectProperty.getClassesId()));
        return AjaxResult.success().put("count", count);
    }

    /**
     * 导出关联属性列表
     */
    @PreAuthorize("@ss.hasPermi('system:objectProperty:export')")
    @Log(title = "关联属性", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(SysObjectProperty sysObjectProperty)
    {
        List<SysObjectProperty> list = sysObjectPropertyService.selectSysObjectPropertyList(sysObjectProperty);
        ExcelUtil<SysObjectProperty> util = new ExcelUtil<SysObjectProperty>(SysObjectProperty.class);
        return util.exportExcel(list, "关联属性数据");
    }

    /**
     * 获取关联属性详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:objectProperty:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(sysObjectPropertyService.selectSysObjectPropertyById(id));
    }

    /**
     * 新增关联属性
     */
    @PreAuthorize("@ss.hasPermi('system:objectProperty:add')")
    @Log(title = "关联属性", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SysObjectProperty sysObjectProperty)
    {

        SysClasses sourceClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getClassesId());
        SysClasses targetClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getRelevanceClassesId());
        dynamicTableService.createOpTable(sourceClasses.getNameEn()+"_"+sysObjectProperty.getField(),
                sourceClasses.getNameZh()+"关联"+targetClasses.getNameZh());
        return toAjax(sysObjectPropertyService.insertSysObjectProperty(sysObjectProperty));
    }

    /**
     * 修改关联属性
     */
    @PreAuthorize("@ss.hasPermi('system:objectProperty:edit')")
    @Log(title = "关联属性", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SysObjectProperty sysObjectProperty)
    {
        return toAjax(sysObjectPropertyService.updateSysObjectProperty(sysObjectProperty));
    }

    /**
     * 删除关联属性
     */
    @PreAuthorize("@ss.hasPermi('system:objectProperty:remove')")
    @Log(title = "关联属性", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        for (Long id : ids) {
            SysObjectProperty sysObjectProperty = sysObjectPropertyService.selectSysObjectPropertyById(id);
            SysClasses sourceClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getClassesId());
            dynamicTableService.deleteTable(sourceClasses.getNameEn()+"_"+sysObjectProperty.getField());
            sysObjectPropertyService.deleteSysObjectPropertyById(id);
        }
        return toAjax(1);
    }


    /**
     * 新增字段判重
     */
    @PreAuthorize("@ss.hasPermi('system:objectProperty:add')")
    @GetMapping("addRemovingRepeat/{classesId}/{nameEn}")
    public AjaxResult commonAddRemovingRepeat(@PathVariable("classesId") Long classesId, @PathVariable("nameEn") String nameEn){
        SysObjectProperty sysObjectProperty = new SysObjectProperty();
        sysObjectProperty.setClassesId(classesId);
        sysObjectProperty.setNameEn(nameEn);
        List<SysObjectProperty> sysObjectProperties = sysObjectPropertyService.selectSysObjectPropertyList(sysObjectProperty);
        if(sysObjectProperties != null && sysObjectProperties.size() > 0){
            return success().put("msg", "字段名不可用，已存在该公共字段");
        }
        return success().put("msg", "success");
    }


//=====================关联数据查询====================================================

    /**
     * 查询关联属性数据列表
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:associate')")
    @GetMapping("/associationList")
    public R associationList() {
        Long objectPropertyId = Long.parseLong(ServletUtils.getParameter("objectPropertyId"));
        SysObjectProperty sysObjectProperty = sysObjectPropertyService.selectSysObjectPropertyById(objectPropertyId);
        SysClasses sourceClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getClassesId());
        SysClasses targetClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getRelevanceClassesId());
        String tableName = ClassesConstants.RESOURCE_TABLE_PREFIX+sourceClasses.getNameEn()+"_"+sysObjectProperty.getField();
        String [] relevanceClassFieldsArr = sysObjectProperty.getRelevanceClassFields().split(",");
        List<SysDataProperty> showList = new ArrayList<>();

        List<SysDataProperty> dataPropertyListCache = dynamicCacheService.getDataPropertyListCache(targetClasses.getNameEn());
        for (String fieldId : relevanceClassFieldsArr) {

            SysDataProperty sysDataProperty = dataPropertyListCache.stream().filter(x -> x.getId() == Long.parseLong(fieldId)).findFirst().orElse(null);
            if(sysDataProperty == null){
                //如果为null刷新缓存再查一次
                dataPropertyListCache = dynamicCacheService.refreshDataPropertyListCache(targetClasses.getNameEn());
                sysDataProperty = dataPropertyListCache.stream().filter(x -> x.getId() == Long.parseLong(fieldId)).findFirst().orElse(null);
            }
            if(sysDataProperty != null){
                if("selectSingle".equals(sysDataProperty.getDataTypeName()) || "selectMultiple".equals(sysDataProperty.getDataTypeName())){
                    SysDictType dictTypeByCache = dynamicCacheService.findDictTypeByCache(sysDataProperty.getDictId());
                    sysDataProperty.setDictType(dictTypeByCache);
                }
                showList.add(sysDataProperty);
            }
        }
        Map<String, Object> condition = new HashMap<>();
        condition.put("=,source_data_id", ServletUtils.getParameter("sourceDataId"));
        List<Map<String, Object>> dynamicOpData = dynamicDataCommonService.getDynamicData(tableName, null, condition, null, ServletUtils.getParameterToInt(TableSupport.PAGE_NUM), ServletUtils.getParameterToInt(TableSupport.PAGE_SIZE));
        List<Map<String, Object>> dynamicData = new ArrayList<>();
        for (Map<String, Object> dynamicDatum : dynamicOpData) {
            Map<String, Object> targetData = dynamicDataService.findDynamicData(targetClasses.getNameEn(), showList.stream().map(x->x.getNameEn()).collect(Collectors.toList()), dynamicDatum.get("target_data_id")+"");
            targetData.put("opId", dynamicDatum.get("id")+"");
            dynamicData.add(targetData);
        }
        Long dynamicCount = dynamicDataCommonService.getDynamicDataCount(tableName, null);
        return R.success().msg("查询成功").data("list", dynamicData).data("total", dynamicCount).data("showField", showList);
    }

    /**
     * 删除关联属性
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:associate')")
    @Log(title = "关联属性", businessType = BusinessType.DELETE)
    @PostMapping("/associationRemove")
    public AjaxResult associationRemove(@RequestBody HashMap<String, Object> dynamic) {
        Long objectPropertyId = Long.parseLong(dynamic.get("objectPropertyId") + "");
        List<String> idsList = (List<String>) dynamic.get("ids");
        SysObjectProperty sysObjectProperty = sysObjectPropertyService.selectSysObjectPropertyById(objectPropertyId);
        SysClasses sourceClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getClassesId());
        String tableName = ClassesConstants.RESOURCE_TABLE_PREFIX+sourceClasses.getNameEn()+"_"+sysObjectProperty.getField();
        Map<String, Object> condition = new HashMap<>();
        condition.put("in,id", idsList);
        dynamicDataCommonService.delDynamicData(tableName, condition);
        return AjaxResult.success();
    }


    /**
     * 新增知识库数据
     */
    @PreAuthorize("@ss.hasPermi('system:dynamic:associate')")
    @Log(title = "知识库管理", businessType = BusinessType.INSERT)
    @PostMapping("/associationAdd")
    public AjaxResult associationAdd(@RequestBody HashMap<String, Object> dynamic){
        Long objectPropertyId = Long.parseLong(dynamic.get("objectPropertyId") + "");
        String sourceDataId = dynamic.get("sourceDataId") + "";
        List<String> idsList = (List<String>) dynamic.get("ids");
        SysObjectProperty sysObjectProperty = sysObjectPropertyService.selectSysObjectPropertyById(objectPropertyId);
        SysClasses sourceClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getClassesId());
        SysClasses targetClasses = sysClassesService.selectSysClassesById(sysObjectProperty.getRelevanceClassesId());
        String tableName = ClassesConstants.RESOURCE_TABLE_PREFIX+sourceClasses.getNameEn()+"_"+sysObjectProperty.getField();
        Map<String, Object> map = null;
        Map<String, Object> conditon = null;
        for (String id : idsList) {
            conditon = new HashMap<>();
            conditon.put("=,source_data_id", sourceDataId);
            conditon.put("=,target_data_id", id);
            Long dynamicDataCount = dynamicDataCommonService.getDynamicDataCount(tableName, conditon);
            if(dynamicDataCount == 0){
                map = new HashMap<>();
                map.put("source_data_id", sourceDataId);
                map.put("target_data_id", id);
                map.put("source_class_en", sourceClasses.getNameEn());
                map.put("target_class_en", targetClasses.getNameEn());
                map.put("create_time", DateUtils.getTime());
                dynamicDataCommonService.addDynamicData(tableName,map);
            }
        }
        return AjaxResult.success("新增成功");
    }




}
